﻿using System;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using User.Api.BizExtensions;
using User.Api.Dto.Card;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace User.Api.Controllers
{
    public class CardController : ApiController
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(CardController));
        private HzfyWeiXinEntities _ctx;

        protected override void Initialize(HttpControllerContext controllerContext)
        {
            _ctx = new HzfyWeiXinEntities();
            base.Initialize(controllerContext);
        }

        protected override void Dispose(bool disposing)
        {
            _ctx.Dispose();
            base.Dispose(disposing);
        }

        /// <summary>
        /// 获取用户的所有就诊卡
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetAll")]
        public GetAllResponse GetAll()
        {
            var azUser = AzUser.GetInApi(Request);
             
            //之前的查询会发生死锁，优化查询为NoLock
            var dbCards = (_ctx.HospCard.Where(x => x.WxUserId == azUser.UserId && x.RecStatus == 1)
                .OrderByDescending(x => x.IsDefault).ThenBy(x => x.CardNo)
                .Select(x => new
                {
                    Id = x.Id,
                    x.CardType,
                    x.CardNo,
                    x.PatientName,
                    x.PatientId,
                    x.IdenNo,
                    x.IsDefault
                })).ToListReadUncommitted();

            var cards = dbCards.Select(x => new GetAllResponse.Card
            {
                Id = x.Id,
                Type = HospCardExtensions.ToCardTypeName(x.CardType),
                Num = x.CardNo??x.PatientId,
                Name = x.PatientName,
                IdenNo = x.IdenNo ?? "",
                IsDefault = x.IsDefault == 1
            }).ToList();

            return new GetAllResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                Cards = cards
            };
        }

        /// <summary>
        /// 设置默认就诊卡
        /// </summary>
        /// <param name="id">就诊卡id</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("SetDefault")]
        public SetDefaultResponse SetDefault(long id)
        {
            var azUser = AzUser.GetInApi(Request);

            var cards = _ctx.HospCard.Where(x => x.WxUserId == azUser.UserId).ToList();
            foreach (var card in cards)
            {
                card.IsDefault = 0;
                if (card.Id == id)
                {
                    card.IsDefault = 1;
                }
            }
            _ctx.SaveChanges();

            return new SetDefaultResponse { ResultCode = "0", ResultMsg = "" };
        }

        /// <summary>
        /// 删除就诊卡
        /// </summary>
        /// <param name="id">就诊卡id</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("Delete")]
        public DeleteResponse Delete(int id)
        {
            var azUser = AzUser.GetInApi(Request);

            var card = _ctx.HospCard.FirstOrDefault(x => x.Id == id && x.WxUserId == azUser.UserId);
            if (card != null)
            {
                card.RecStatus = 2;
                card.RecDeleteDt = DateTime.Now;
           
                _ctx.SaveChanges();

                // 如果删除了默认卡，则自动设置其余卡号小的卡为默认就诊卡
                if (card.IsDefault == 1)
                {
                    var cards = _ctx.HospCard.Where(x => x.RecStatus == 1 && x.WxUserId == azUser.UserId)
                        .OrderBy(x => x.CardNo).ToList();
                    for (int i = 0; i < cards.Count; i++)
                    {
                        cards[i].IsDefault = i == 0 ? 1 : 0;
                    }
                    _ctx.SaveChanges();
                }
            }

            return new DeleteResponse { ResultCode = "0", ResultMsg = "" };
        }

        /// <summary>
        /// 绑定就诊卡
        /// </summary>
        /// <param name="isDefault">是否设置为默认就诊卡</param>
        /// <param name="type">卡类型</param>
        /// <param name="num">卡号</param>
        /// <param name="name">姓名</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("AddBinding")]
        public AddBindingResponse AddBinding(bool isDefault, int type, string num, string name)
        {
            var azUser = AzUser.GetInApi(Request);

            var cardMax = ConfigurationManager.AppSettings["CardMax"].ToInt32();
            var cardCount = _ctx.HospCard
                .Count(x => x.WxUserId == azUser.UserId && x.RecStatus == 1);
            if (cardCount >= cardMax)
            {
                return new AddBindingResponse
                {
                    ResultCode = "1",
                    ResultMsg = "最多可以添加" + cardMax + "张就诊卡!"
                };
            }

            if (cardCount == 0)
            {
                isDefault = true;
            }

            var existCard =
                _ctx.HospCard.FirstOrDefault(x => x.RecStatus == 1 && x.CardNo == num && x.WxUserId == azUser.UserId);
            if (existCard != null)
            {
                return new AddBindingResponse
                {
                    ResultCode = "2",
                    ResultMsg = "您已添加过该就诊卡!"
                };
            }

            // 获取院内就诊卡信息
            var request = new GetPatientInfoRequest();
            request.CardNo = num;
            request.PatientID = "";
            request.PatientName = name;
            //request.CardType = type.ToString();

            GetPatientInfoResponse response;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPatientInfo", request).Result;
                responseMsg.EnsureSuccessStatusCode();
                response = responseMsg.Content.ReadAsAsync<GetPatientInfoResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内获取病人信息Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                return new AddBindingResponse
                {
                    ResultCode = "3",
                    ResultMsg = "操作失败，获取就诊卡信息超时"
                };
            }

            if (response.ResultCode != "0")
            {
                // 获取院内就诊卡信息
                request.PatientID = num;
                request.CardNo = "";
                request.PatientName = name;
                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPatientInfo", request).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    response = responseMsg.Content.ReadAsAsync<GetPatientInfoResponse>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("调用院内获取病人信息Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                    return new AddBindingResponse
                    {
                        ResultCode = "3",
                        ResultMsg = "操作失败，获取就诊卡信息超时"
                    };
                }
                if (response.ResultCode != "0")
                {
                    return new AddBindingResponse
                    {
                        ResultCode = "5",
                        ResultMsg = response.ResultDesc
                    };
                }
                if (response.PatientInfo.Name.Trim() != name.Trim())
                {
                    return new AddBindingResponse
                    {
                        ResultCode = "6",
                        ResultMsg = "卡号与姓名不匹配"
                    };
                }
            }
            if (response.PatientInfo.Name.Trim() != name.Trim())
            {
                // 获取院内就诊卡信息
                request.PatientID = num;
                request.CardNo = "";
                request.PatientName = name;
                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPatientInfo", request).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    response = responseMsg.Content.ReadAsAsync<GetPatientInfoResponse>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("调用院内获取病人信息Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                    return new AddBindingResponse
                    {
                        ResultCode = "3",
                        ResultMsg = "操作失败，获取就诊卡信息超时"
                    };
                }
                if (response.ResultCode != "0")
                {
                    return new AddBindingResponse
                    {
                        ResultCode = "5",
                        ResultMsg = response.ResultDesc
                    };
                }
                if (response.PatientInfo.Name.Trim() != name.Trim())
                {
                    return new AddBindingResponse
                    {
                        ResultCode = "6",
                        ResultMsg = "卡号与姓名不匹配"
                    };
                }
            }
            var newCard = new HospCard
            {
                WxUserId = azUser.UserId,
                CardType = type.ToInt32(),
                CardNo = num.Trim(),
                PatientName = response.PatientInfo.Name.Trim(),
                RecStatus = 1,
                RecCreateDt = DateTime.Now,
                RecUpdateDt = DateTime.Now,
                PatientId = response.PatientInfo.PatientId.Trim(),
                //InDeptNo = response.PatientInfo.InDeptNo.Trim(),
                //Name = response.PatientInfo.Name.Trim(),
                //Gender = response.PatientInfo.Gender.Trim(),
                //Age = response.PatientInfo.Age.Trim(),
                //Birthdate = response.PatientInfo.Birthdate.Trim(),
                IdenNo = response.PatientInfo.IdenNo.Trim(),
                Phone = response.PatientInfo.Phone.Trim(),
                FeeType = response.PatientInfo.FeeType.Trim()
            };
            _ctx.HospCard.Add(newCard);
            _ctx.SaveChanges();

            var existsCards = _ctx.HospCard.Where(x => x.CardNo == newCard.CardNo);
            foreach (var existsCard in existsCards)
            {
                existsCard.RecUpdateDt = DateTime.Now;
                existsCard.PatientName = newCard.PatientName;
                existsCard.PatientId = newCard.PatientId;
                //existsCard.InDeptNo = newCard.InDeptNo;
                //existsCard.Name = newCard.Name;
                //existsCard.Gender = newCard.Gender;
                //existsCard.Age = newCard.Age;
                //existsCard.Birthdate = newCard.Birthdate;
                existsCard.IdenNo = newCard.IdenNo;
                existsCard.Phone = newCard.Phone;
                existsCard.FeeType = newCard.FeeType;
            }
            _ctx.SaveChanges();

            if (isDefault)
            {
                SetDefault(newCard.Id);
            }

            return new AddBindingResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                Id = newCard.Id,
                Type = HospCardExtensions.ToCardTypeName(newCard.CardType),
                Num = newCard.CardNo?? newCard.PatientId,
                Name = newCard.PatientName,
                IsDefault = newCard.IsDefault == 1,
                IsSelected = false
            };
        }

        /// <summary>
        /// 创建虚拟就诊卡
        /// </summary>
        /// <param name="name">姓名</param>
        /// <param name="certNo">身份证号码</param>
        /// <param name="phone">联系电话</param>
        /// <param name="address">住址</param>
        /// <param name="isDefault">是否设置为默认就诊卡</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("AddNew")]
        public AddNewResponse AddNew(string name, string certNo, string phone, string address, bool isDefault)
        {
            var azUser = AzUser.GetInApi(Request);

            var cardMax = ConfigurationManager.AppSettings["CardMax"].ToInt32();
            var cardCount = _ctx.HospCard
                .Count(x => x.WxUserId == azUser.UserId && x.RecStatus == 1);
            if (cardCount >= cardMax)
            {
                return new AddNewResponse
                {
                    ResultCode = "1",
                    ResultMsg = "最多可以添加" + cardMax + "张就诊卡!"
                };
            }

            if (cardCount == 0)
            {
                isDefault = true;
            }

            var existCard =
                _ctx.HospCard.FirstOrDefault(x => x.RecStatus == 1 && x.Name == name && x.IdenNo == certNo && x.WxUserId == azUser.UserId);
            if (existCard != null)
            {
                return new AddNewResponse
                {
                    ResultCode = "2",
                    ResultMsg = "您已添加过该身份证!"
                };
            }

            DateTime birthDt;
            string sex;
            var isValidCertNo = HospCardExtensions.IsValidCertNo(certNo, out birthDt, out sex);
            if (!isValidCertNo)
            {
                return new AddNewResponse
                {
                    ResultCode = "2",
                    ResultMsg = "无效的身份证号码"
                };
            }

            // 创建就诊卡
            var createCardRequest = new CreateCardRequest();
            createCardRequest.IdenNo = certNo;
            createCardRequest.Name = name;
            createCardRequest.Birthdate = birthDt.ToString("yyyy-MM-dd");
            createCardRequest.Gender = sex == "男" ? "1":"2";
            createCardRequest.Phone = phone;
            createCardRequest.Address = address;

            CreateCardResponse createCardResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/CreateCard", createCardRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                createCardResponse = responseMsg.Content.ReadAsAsync<CreateCardResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内创建就诊卡Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                return new AddNewResponse
                {
                    ResultCode = "3",
                    ResultMsg = "操作失败，创建就诊卡超时"
                };
            }

            if (createCardResponse.ResultCode != "0")
            {
                return new AddNewResponse
                {
                    ResultCode = "4",
                    ResultMsg = createCardResponse.ResultDesc
                };
            }

            // 获取院内就诊卡信息
            var getPatientRequest = new GetPatientInfoRequest();
            getPatientRequest.CardNo = createCardResponse.CardNo;
            getPatientRequest.PatientID = createCardResponse.PatientId;

            GetPatientInfoResponse getPatientResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPatientInfo", getPatientRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                getPatientResponse = responseMsg.Content.ReadAsAsync<GetPatientInfoResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内获取病人信息Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                return new AddNewResponse
                {
                    ResultCode = "5",
                    ResultMsg = "操作失败，获取就诊卡信息超时"
                };
            }

            if (getPatientResponse.ResultCode != "0")
            {
                return new AddNewResponse
                {
                    ResultCode = "6",
                    ResultMsg = getPatientResponse.ResultDesc
                };
            }

            var newCard = new HospCard
            {
                WxUserId = azUser.UserId,
                CardType = 0,
                CardNo = getPatientResponse.PatientInfo.PatientId.Trim(),
                PatientName = getPatientResponse.PatientInfo.Name.Trim(),
                RecStatus = 1,
                RecCreateDt = DateTime.Now,
                RecUpdateDt = DateTime.Now,
                PatientId = getPatientResponse.PatientInfo.PatientId.Trim(),
                //InDeptNo = getPatientResponse.PatientInfo.InDeptNo.Trim(),
                //Name = getPatientResponse.PatientInfo.Name.Trim(),
                //Gender = getPatientResponse.PatientInfo.Gender.Trim(),
                //Age = getPatientResponse.PatientInfo.Age.Trim(),
                //Birthdate = getPatientResponse.PatientInfo.Birthdate.Trim(),
                IdenNo = getPatientResponse.PatientInfo.IdenNo.Trim(),
                Phone = getPatientResponse.PatientInfo.Phone.Trim(),
                FeeType = getPatientResponse.PatientInfo.FeeType.Trim()
            };

            _ctx.HospCard.Add(newCard);
            _ctx.SaveChanges();

            var existsCards = _ctx.HospCard.Where(x => x.CardNo == newCard.CardNo);
            foreach (var existsCard in existsCards)
            {
                existsCard.RecUpdateDt = DateTime.Now;
                existsCard.PatientName = newCard.PatientName;
                existsCard.PatientId = newCard.PatientId;
                //existsCard.InDeptNo = newCard.InDeptNo;
                //existsCard.Name = newCard.Name;
                //existsCard.Gender = newCard.Gender;
                //existsCard.Age = newCard.Age;
                //existsCard.Birthdate = newCard.Birthdate;
                existsCard.IdenNo = newCard.IdenNo;
                existsCard.Phone = newCard.Phone;
                existsCard.FeeType = newCard.FeeType;
            }
            _ctx.SaveChanges();

            if (isDefault)
            {
                SetDefault(newCard.Id);
            }

            return new AddNewResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                Id = newCard.CardNo.ToInt32(),
                Type = HospCardExtensions.ToCardTypeName(newCard.CardType),
                Num = newCard.CardNo??newCard.PatientId,
                Name = newCard.PatientName,
                IsDefault = newCard.IsDefault == 1,
                IsSelected = false
            };
        }
    }
}
